{-# LANGUAGE OverloadedStrings #-}

--------------------------------------------------------------------------------
--  OBJET            : library that deals with logging problems
--------------------------------------------------------------------------------
--  AUTHOR           : Sarfraz Kapasi
--  DATE             : 20.11.201
--  VERSION          : 0.0.0.2
--  LICENCE          : GPL-3
--------------------------------------------------------------------------------
--  DESCRIPTION
--     N/A
--  USAGE CASE
--     This module should be used mainly on IO sequence
--       to keep track side effects
--  DEPENDENCIES
--     N/A
--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
-- Exports

module Log  where

--------------------------------------------------------------------------------
-- Imports

import Control.Monad (when)
import System.IO
import System.Exit

--------------------------------------------------------------------------------
-- Datatypes

type Log = Handle

--------------------------------------------------------------------------------
-- Pure functions
-- N/A
--------------------------------------------------------------------------------
-- Impure functions

-- |This function initiate the log
initLog :: FilePath -- ^ path to log file
        -> IO Log   -- ^ log object
initLog path = openFile path AppendMode

-- | This function closes the log
closeLog :: Log   -- ^ log object
         -> IO ()
closeLog log = hClose log

-- |This function adds a info entry to log
addInfo :: Log    -- ^ log object
        -> String -- ^ function of origin
        -> String -- ^ info message
        -> IO ()
addInfo log func msg = do
  let
    entry = "[INFO]-["++func++"]-"++msg
  hPutStrLn log entry
  putStrLn entry

-- |This function adds a warning entry to log
addWarning :: Log    -- ^ log object
           -> String -- ^ function of origin
           -> String -- ^ warning message
           -> IO ()
addWarning log func msg = do
  let
    entry = "[WARNING]-["++func++"]-"++msg
  hPutStrLn log entry
  hPutStrLn stderr entry

-- |This function adds a debug message to log if debug switch is True
addDebug :: Bool   -- ^ debug switch
         -> Log    -- ^ log object
         -> String -- ^ function of origin
         -> String -- ^ debug message
         -> IO ()
addDebug switch log func msg = when switch $ do
  let
    entry = "[DEBUG]-["++func++"]-"++msg
  hPutStrLn log entry
  putStrLn entry

-- |This function logs a critical exeption and terminate program
addCritical :: Log    -- ^ log object
            -> String -- ^ function of origin
            -> String -- ^ critical message
            -> IO ()
addCritical log func msg = do
  let
    entry = "[CRITICAL]-["++func++"]-"++msg
  hPutStrLn log entry
  hClose log
  hPutStrLn stderr entry
  exitFailure

--------------------------------------------------------------------------------
-- eof
